package com.dhcc.bpm.modules.api.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.common.annotation.Log;
import com.dhcc.bpm.common.constant.FilePathConstant;
import com.dhcc.bpm.common.enums.BusinessType;
import com.dhcc.bpm.common.json.JSONObject;
import com.dhcc.bpm.common.utils.ExcelUtil;
import com.dhcc.bpm.modules.api.entity.Backservice;
import com.dhcc.bpm.modules.api.entity.Externalcall;
import com.dhcc.bpm.modules.api.service.IBackserviceService;
import com.dhcc.bpm.modules.api.service.IExternalcallService;
import com.dhcc.bpm.modules.api.vo.BackserviceVO;
import com.dhcc.bpm.modules.api.vo.ExternalcallVO;
import com.dhcc.bpm.modules.common.entity.Plupload;
import com.dhcc.bpm.modules.common.entity.Upload;
import com.dhcc.bpm.modules.common.service.IPluploadService;
import com.dhcc.bpm.modules.system.service.ISerialNumberService;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName BackserviceController
 * @Description 后端服务表 控制器
 * @Author daina
 * @Date 2020/2/25 13:14
 * @Version V1.0
 * @Copyright: 2020 东华软件 . All rights reserved.
 */
@RestController
@AllArgsConstructor
@NoArgsConstructor
@RequestMapping("bpm-api/backservice")
@Api(value = "后端服务表", tags = "后端服务表接口")
public class BackserviceController extends BladeController {
	private static final Logger log = LoggerFactory.getLogger(BackserviceController.class);
	@Autowired
	private IBackserviceService backserviceService;
	@Autowired
	private ISerialNumberService serialNumberService;
	@Autowired
	private IExternalcallService externalcallService;
	@Autowired
	private IPluploadService pluploadService;
	private String path;
	@Value("${bpm.file-public-path}")
	public void setFileUploadPath(String publicPath) {
		path = publicPath + FilePathConstant.SQLPATH;
	}

	private List<String> supportExcelType = Lists.newArrayList( "xls", "xlsx");

	/**
	 * @Description 详情
	 * @Author daina
	 * @Date 14:47 2020/2/25
	 * @param backserviceVO
	 * @return org.springblade.core.tool.api.R<com.dhcc.bpm.modules.api.entity.Backservice>
	 **/
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入backservice")
	@Log(title = "查询后端服务表详情", businessType = BusinessType.SELECT)
	@ApiLog("查询后端服务表详情")
	public R<BackserviceVO> detail(BackserviceVO backserviceVO) {
		BackserviceVO backservice = null;
		Backservice detail = backserviceService.getOneDetail(backserviceVO);
		if(detail != null){
			backservice = new BackserviceVO();
			BeanUtils.copyProperties(detail, backservice);
			List<ExternalcallVO> externalcall = externalcallService.getByBackServiceId(detail.getId());
			if(externalcall != null && externalcall.size() > 0){
				backservice.setIp(externalcall.get(0).getIp() + ":" + externalcall.get(0).getPort());
			}
		}
		return R.data(backservice);
	}

	/**
	 * @Description 分页 后端服务表
	 * @Author daina
	 * @Date 14:47 2020/2/25
	 * @param backservice
	 * @param query
	 * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.api.entity.Backservice>>
	 **/
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入backservice")
	@Log(title = "查询后端服务表", businessType = BusinessType.SELECT)
	@ApiLog("查询后端服务表")
	public R<IPage<BackserviceVO>> list(BackserviceVO backservice, Query query) {
		//IPage<Backservice> pages = backserviceService.page(Condition.getPage(query), Condition.getQueryWrapper(backservice,Backservice.class).lambda().orderByDesc(Backservice::getCreateTime));
		IPage<BackserviceVO> pages = backserviceService.getPage(Condition.getPage(query),backservice) ;
		return R.data(pages);
	}

	/**
	 * @Description 自定义分页 后端服务表
	 * @Author daina
	 * @Date 14:47 2020/2/25
	 * @param backservice
	 * @param query
	 * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage<com.dhcc.bpm.modules.api.vo.BackserviceVO>>
	 **/
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入backservice")
	@Log(title = "查询后端服务表", businessType = BusinessType.SELECT)
	@ApiLog("查询后端服务表")
	public R<IPage<BackserviceVO>> page(BackserviceVO backservice, Query query) {
		IPage<BackserviceVO> pages = backserviceService.selectBackservicePage(Condition.getPage(query), backservice);
		return R.data(pages);
	}

	/**
	 * @Description 新增 后端服务表
	 * @Author daina
	 * @Date 14:47 2020/2/25
	 * @param backservice
	 * @return org.springblade.core.tool.api.R
	 **/
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入backservice")
	@Log(title = "新增 后端服务表", businessType = BusinessType.INSERT)
	@ApiLog("新增 后端服务表")
	public R save(@Valid @RequestBody Backservice backservice) {
		return R.status(backserviceService.save(backservice));
	}

	@ApiLog("导入excel")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "导入excel", notes = "sysNum")
	@Log(title = "导入excel",businessType = BusinessType.SELECT)
	@PostMapping("importexcel")
	public R importexcel(Plupload plupload, HttpServletRequest request) {
		String name = null;
		Upload upload = new Upload();
		upload.setRequest(request);
		Upload uploadEntity = pluploadService.getFile(upload);
		MultipartFile file = uploadEntity.getMultipartFile();
		name = file.getOriginalFilename();
		String fileType = name.substring(name.lastIndexOf(".") + 1);
		if(!supportExcelType.contains(fileType)){
			return R.fail("请上传excel类型文档！");
		}
		uploadEntity.setName(name);
		//本地上传
		String id = pluploadService.fileLocalUpload(plupload, upload, request).toString();
		Plupload newupload = pluploadService.selectById(Long.parseLong(id));
		try (InputStream inputStream = new FileInputStream(new File(path + "/"  + newupload.getFileRealname()))){
			ExcelUtil<Backservice> excelUtil = new ExcelUtil<Backservice>(Backservice.class);
			List<Backservice> list = excelUtil.importExcel("API后端服务信息表", inputStream);
			for (Backservice sys : list) {
				try {
					backserviceService.save(sys);
				} catch (Exception e) {
					log.error("数据库异常：{}", e);
					if (e.getMessage().contains("for key 'sys_name_idx'") || e.getMessage().contains("ORA-00001")) {
						continue;
					}else {
						return R.fail(500, "数据库异常");
					}
				} finally {

				}
			}
			pluploadService.fileDelete(Long.parseLong(id));
		} catch (FileNotFoundException e) {
			log.error("异常信息:{}", e);
		} catch (Exception e) {
			log.error("异常信息:{}", e);
		}
		return R.success("导入成功");
	}

	/**
	 * @Description 修改 后端服务表
	 * @Author daina
	 * @Date 14:47 2020/2/25
	 * @param backservice
	 * @return org.springblade.core.tool.api.R
	 **/
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入backservice")
	@Log(title = "修改后端服务表", businessType = BusinessType.UPDATE)
	@ApiLog("修改后端服务表")
	public R update(@Valid @RequestBody Backservice backservice) {
		return R.status(backserviceService.updateById(backservice));
	}

	/**
	 * @Description 新增或修改 后端服务表
	 * @Author daina
	 * @Date 14:47 2020/2/25
	 * @param backservice
	 * @return org.springblade.core.tool.api.R
	 **/
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入backservice")
	@Log(title = "新增或修改后端服务表", businessType = BusinessType.INSERT)
	@ApiLog("新增或修改后端服务表")
	@Transactional(rollbackFor = Exception.class)
	public R submit(@Valid @RequestBody Backservice backservice, @RequestBody JSONObject obj) {
		if(null == backservice.getId() || backservice.getId() <= 0){
			String code = serialNumberService.generateSerialNumberByModelCode("opc_backservice");
			// safeType 安全认证类型 0：签名加密 ； 1：签名；  2：加密 ； 3：明文
			backservice.setSafeType(0L);
			backservice.setBackserviceCode(code);
		}
		boolean status;
		try {
			//服务名去除空格  修改时间：20201026 09:20
			if(backservice.getApplicationName() != null){
				backservice.setApplicationName(backservice.getApplicationName().trim().replaceAll(" ", ""));
			}
			status = backserviceService.saveOrUpdate(backservice);
		} catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			if (e.getMessage().contains("for key 'backservice_name_idx'") || e.getMessage().contains("ORA-00001")) {
				return R.fail(500, "该后端服务已存在");
			}
			return R.fail(500, "数据库异常");
		} finally {

		}

		//删除后端服务外部调用数据
		externalcallService.getByBackServiceId(backservice.getId()).forEach(externalcallVO -> {
			externalcallService.removeById(externalcallVO.getId());
		});

		//  applyType 服务调用类型(1：内部调用，2：外部调用)
		String applyType = "2";
		if (backservice.getApplyType().equals(applyType)) {
			JSONObject.JSONArray list = obj.getArr("excallKeysNames");
			if (status && null != list && list.size() > 0) {
				Externalcall ec = new Externalcall();
				ec.setBackserviceId(backservice.getId());
				for (int i = 0; i < list.size(); i++) {
					String [] str = list.get(i).toString().split(":");
					ec.setIp(str[0]);
					ec.setPort(Long.valueOf(str[1]));
					externalcallService.saveOrUpdate(ec);
					ec.setId(null);
				}
			}
		}
		return R.status(status);
	}


	/**
	 * @Description  删除 后端服务表
	 * @Author daina
	 * @Date 14:48 2020/2/25
	 * @param ids
	 * @return org.springblade.core.tool.api.R
	 **/
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	@Log(title = "逻辑删除", businessType = BusinessType.DELETE)
	@ApiLog("逻辑删除")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(backserviceService.deleteLogic(Func.toLongList(ids)));
	}

	/**
	 * @Description 系统服务名关联查询
	 * @Author daina
	 * @Date 14:48 2020/2/25
	 * @param
	 * @return com.dhcc.bpm.common.json.JSONObject
	 **/
	@GetMapping("/selectBackserviceName")
	@ApiOperationSupport(order = 8)
	@ApiOperation(value = "查询所有系统名称", notes = "无参")
	@Log(title = "查询所有系统名称", businessType = BusinessType.SELECT)
	@ApiLog("查询所有系统名称")
	public JSONObject selectBySysName() {
		JSONObject object = new JSONObject();
		object.put("success",true);
		object.put("names",backserviceService.selectBackserviceName());
		return object;
	}

	@PostMapping("/download")
	public void download(BackserviceVO backservice, HttpServletResponse response){
		int page = 1;
		List<BackserviceVO> BaseProductVO = new ArrayList<>();
		while (true) {
			Query query = new Query();
			query.setCurrent(page++);
			query.setSize(10);
			IPage<BackserviceVO> pages = backserviceService.getPage(Condition.getPage(query),backservice) ;
			// 统计api 信息  (响应次数、响应成功率、响应时间)
			if (pages.getRecords() != null && pages.getRecords().size() > 0) {
				BaseProductVO.addAll(pages.getRecords());
			}else {
				break;
			}
		}


		ExcelUtil<BackserviceVO> util = new ExcelUtil<BackserviceVO>(BackserviceVO.class);
		util.exportExcel(BaseProductVO,"API后端服务信息表",response);
	}

}
